package cn.genmer.test.security.source;

import lombok.Synchronized;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.framework.AopProxyFactory;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilterInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.nio.Buffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 查看源码
 */
@Component
public class lookSource {
    static int[] a;
    public static void main(String[] args) throws FileNotFoundException {
        // 查看isEmpty源码
//        Collection collection = new Collection();
//        collection.isEmpty();

//        StringUtils.isBlank()
//        StringUtils.isNotBlank()
//        Collections.emptyList()

//        底层设定了2个阈值，第一个286，大于走归并排序，小于走快速排序（这里面还有个阈值47，大于走快排，小于走插入排序）
//        Arrays.sort();
        // 底层list.sort list是个接口，实现子类就是Arrays
//        Collections.sort();

        // 原型模式 applicationContext。getBean()  里有一个判断是否单例、是否原型（isPrototype）的代码
//        ApplicationContext applicationContext = new ApplicationContext();


        // 简单工厂模式使用
//        Calendar.getInstance();

//        String 不可变，导致每次创建新的对象，但是传递是跟基本数据类型一样的
//        String

        // 装饰者模式在IO模式的应用
//        DataInputStream dis = new DataInputStream(new FileInputStream(("D://test.txt")));
//        FilterInputStream
        // 观察者模式使用在了Observable - 在jdk9废弃

        // AOP测试
//        concatString();

        // AOP 动态代理原理
//        AopProxyFactory

//        Hashtable Enumeration

//        Collections
//        HashMap - 1.8底层Node存储 1.7 Entity
//        reverseInteger();

//        System.out.println(17^5);
//        new Hashtable(); // 继承自Dictionary， 实现类Map 序列化 - 线程安全
//        new HashMap();  // AbstractMap， 实现类Map 序列化 - 线程不安全
//        new Properties();
//        String aa = new String("aa");
//        aa.intern();  // 返回常量池的引用地址
        String str="aa";
        StringBuilder builder = new StringBuilder();
        builder.indexOf("");
//        System.out.println(str == aa.intern);

//        Buffer
        // bigDecimal底层计算是long之间的计算
//        BigDecimal bigDecimal = new BigDecimal(2.0);
//        bigDecimal.add(bigDecimal);

        // 默认数组null
//        System.out.println(a);
//        Lock Reen;
//        Synchronized
//        voila

//        new Thread().isDaemon(); // 可以通过set isDaemon这个参数来指定或者查看线程是否是后台线程（守护线程）

        // Bean 实例化生命周期种，最重要的两个接口
//        InstantiationAwareBeanPostProcessor
//                beanPostProcessor
//        AbstractBeanFactory

//        ApplicationContext
//        ArrayList
//        LinkedList
//        Vector
//        HashMap
//                Hashtablep
        // 原子工具包
        AtomicReference atomicReference = new AtomicReference(10);
        atomicReference.compareAndSet(null,null);

        // copyOnWrite 写时复制缺点1。 内存占用问题 2。数据一致性
//        CopyOnWriteArrayList

        // jion 底层使用wait
//        Thread t = new Thread();
//        t.join();

//        Condition
    }


    @PostConstruct
    public static String concatString(){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("a");
        System.out.println("concatString方法执行");
        return stringBuffer.toString();
    }

    public static void reverseInteger() {
        int number = 125;
        // write your code here
        String s = String.valueOf(number);
        s =  s == null ? null : (new StringBuilder(s)).reverse().toString();
        int result = Integer.parseInt(s);
        System.out.println(result);
    }

    /**
     * Map转成实体对象
     * @param map map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
        if (map == null) {
            return null;
        }
        Object obj = null;
        try {
            // 获取实例
            obj = clazz.newInstance();
            // 获取属性数组
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                // 获取成员变量的权限修饰符
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                // 遍历map，找到一个值设置到对象里就返回
                for (Map.Entry<String, Object> entry : map.entrySet()) {
                    if (field.getName().equals(entry.getKey())){
                        field.set(obj, entry.getValue());
                        return obj;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 获取map中第一个数据值
     *
     * @param map 数据源
     * @return
     */
    private static Object getFirst(Map<String, Object> map) {
        Object obj = null;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            entry.getKey();
            obj = entry.getValue();
            if (obj != null) {
                break;
            }
        }
        return  obj;
    }
}
